package org.csu.softwaremetrics_demo.entity.result.impl;

import org.csu.softwaremetrics_demo.entity.common.LKMetricSingleClass;
import org.csu.softwaremetrics_demo.entity.result.Result;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description: LK度量结果类，用于存储和操作所有类的LKMetricSingleClass对象。
 * @Author: Jukomu
 * @Package: org.csu.softwaremetrics_demo.entity.result
 * @Project: SoftwareMetrics_demo
 * @name: LKMetricResult
 * @Date: 2025/4/6-20:16
 * @Filename: LKMetricResult
 */
public class LKMetricResult implements Result<LKMetricSingleClass> {
    // 存储LKMetricSingleClass对象的映射，键为文件名，值为LKMetricSingleClass对象
    private final Map<String, LKMetricSingleClass> results;

    // 构造函数，初始化results为空HashMap
    public LKMetricResult() {
        this.results = new HashMap<>();
    }

    // 构造函数，接收一个Map参数并赋值给results
    public LKMetricResult(Map<String, LKMetricSingleClass> results) {
        this.results = results;
    }

    // 实现Result接口的add方法，将LKMetricSingleClass对象添加到results中
    @Override
    public void add(LKMetricSingleClass obj) {
        results.put(obj.getFile(), obj);
    }

    // 实现Result接口的get方法，根据文件名获取对应的LKMetricSingleClass对象
    @Override
    public LKMetricSingleClass get(String name) {
        return results.get(name);
    }

    // 实现Result接口的all方法，返回results中所有LKMetricSingleClass对象的集合
    @Override
    public Collection<LKMetricSingleClass> all() {
        return results.values();
    }

    // 实现Result接口的getByClassName方法，根据类名查找并返回对应的LKMetricSingleClass对象
    @Override
    public LKMetricSingleClass getByClassName(String name) {
        for (LKMetricSingleClass singleMetric : results.values()) {
            if (singleMetric.getClassName().equals(name)) {
                return singleMetric;
            }
        }
        return null;
    }

    /**
     * 批量添加度量结果
     * @param metrics 要添加的度量结果列表
     */
    public void setMetrics(Collection<LKMetricSingleClass> metrics) {
        if (metrics == null) {
            return;
        }
        metrics.forEach(this::add);
    }

    /**
     * 计算每个指标的软件复杂性指数（SI）。
     *
     * 该方法首先计算所有指标的总nom值，然后根据每个指标的noo和dit值计算其SI值。
     * 具体计算公式为：SI = NOO * DIT / NOM_Total
     */
    public void calculateSI(){
        // 初始化总nom值为0
        int nomTotal = 0;

        // 遍历所有指标，累加每个指标的nom值
        for (LKMetricSingleClass singleMetric : results.values()) {
            nomTotal += singleMetric.getNom();
        }

        // 再次遍历所有指标，计算每个指标的SI值
        for (LKMetricSingleClass singleMetric : results.values()) {
            // 计算当前指标的SI值
            double si = singleMetric.getNoo() * singleMetric.getDit() / (double) nomTotal;
            // 设置当前指标的SI值
            singleMetric.setSi(si);
        }
    }
}
